﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Map.Data
{
    /// <summary>
    /// 六边形地图网格点
    /// </summary>
    public class MapPoint3D
    {
        private int _x = 0, _y = 0, _z = 0;
        public int X { get { return _x; } set { _x = value; } }
        public int Y { get { return _y; } set { _y = value; } }
        public int Z { get { return _z; } set { _z = value; } }
        /// <summary>
        /// 在不确定3个值都绝对正确的情况下请慎用3个参数的构造函数
        /// </summary>
        private MapPoint3D(int x, int y,int z)
        {
            _x = x;
            _y = y;
            _z = z;
        }
        /// <summary>
        /// 通过索引坐标构造
        /// </summary>
        public MapPoint3D(int indexX, int indexY)
        {
            var point =  Index2DAtMapPoint3D(indexX, indexY);
            _x = point.X;
            _y = point.Y;
            _z = point.Z;
        }
        public static MapPoint3D Zero
        {
            get { return new MapPoint3D(0, 0, 0); }
        }
        /// <summary>
        /// 取MapPoint3D通过XY值取
        /// </summary>
        public static MapPoint3D GetMapPoint3DAt_XY(int x,int y)
        {
            return new MapPoint3D(x, y, GetZ(x, y));
        }
        /// <summary>
        /// 取MapPoint3D通过XZ值取
        /// </summary>
        public static MapPoint3D GetMapPoint3DAt_XZ(int x, int z)
        {
            return new MapPoint3D(x, GetY(x, z), z);
        }
        /// <summary>
        /// 取MapPoint3D通过YZ值取
        /// </summary>
        public static MapPoint3D GetMapPoint3DAt_YZ(int y, int z)
        {
            return new MapPoint3D(GetX(y, z), y, z);
        }
        /// <summary>
        /// Map3D点转换为索引点
        /// </summary>
        public static MapPoint2D MapPoint3DAtIndex2D(int x,int y,int z)
        {
            var indexY = x;
            var indexX = y;
            if (y > 0)
                x = z - (x + x%2)/2;
            if (y < 0)
                x = y + (x + x%2)/2;
            return new MapPoint2D(x, y);
        }
        /// <summary>
        /// Map3D点转换为索引点
        /// </summary>
        public static MapPoint2D MapPoint3DAtIndex2D( MapPoint3D mapPoint3D)
        {
            return MapPoint3DAtIndex2D(mapPoint3D.X, mapPoint3D.Y, mapPoint3D.Z);
        }

        public MapPoint2D MapPoint3DAtIndex2D()
        {
            return MapPoint3DAtIndex2D(this);
        }
        /// <summary>
        /// 索引坐标转换为Map3D点
        /// </summary>
        public static MapPoint3D Index2DAtMapPoint3D(MapPoint2D index2D)
        {
            return Index2DAtMapPoint3D(index2D.X, index2D.Y);
        }
        public static MapPoint3D Index2DAtMapPoint3D(int indexX,int indexY)
        {
            var x = indexY;
            var y = indexX;
            var z = indexX;
            if (x > 0)
            {
                z = (x + x%2)/2 + z;
                y = GetY(x, z);
            }
            if (x < 0)
            {
                y = y - (x + x%2)/2;
                z = GetZ(x, y);
            }
            return new MapPoint3D(x, y, z);
        }
        /// <summary>
        /// 基于XY的Map2D点
        /// </summary>
        public MapPoint2D Point2DAtXY
        {
            get { return new MapPoint2D(_x, _y); }
            set
            {
                _x = value.X;
                _y = value.Y;
                _z = GetZ(_x, _y);
            }
        }
        /// <summary>
        /// Map点的步长
        /// </summary>
        public int Magnitude
        {
            get
            {
                return Mathf.Max(Mathf.Max(Mathf.Abs(_x), Mathf.Abs(_y)), Mathf.Abs(_z));
            }
        }
        /// <summary>
        /// 基于XZ的Map2D点
        /// </summary>
        public MapPoint2D Point2DAtXZ
        {
            get { return new MapPoint2D(_x, _z); }
            set
            {
                _x = value.X;
                _z = value.Y;
                _y = GetY(_x, _z);
            }
        }
        /// <summary>
        /// 基于XZ的Map2D点
        /// </summary>
        public MapPoint2D Point2DAtYZ
        {
            get { return new MapPoint2D(_y, _z); }
            set
            {
                _y = value.X;
                _z = value.Y;
                _x = GetX(_y, _z);
            }
        }
        /// <summary>
        /// 通过XY取Z
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public static int GetZ(int x,int y)
        {
            return x + y;
        }
        /// <summary>
        /// 通过XZ取Y
        /// </summary>
        /// <param name="x"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public static int GetY(int x, int z)
        {
            return z - x;
        }
        /// <summary>
        /// 通过YZ取X
        /// </summary>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public static int GetX(int y,int z)
        {
            return z - y;
        }
        public static MapPoint3D operator +(MapPoint3D thisPint, MapPoint3D targetPoint)
        {
            return new MapPoint3D(thisPint._x + targetPoint._x,
                thisPint._y + targetPoint._y,
                thisPint._z + targetPoint._z);
        }
        public static MapPoint3D operator -(MapPoint3D thisPint, MapPoint3D targetPoint)
        {
            return new MapPoint3D(thisPint._x - targetPoint._x,
                thisPint._y - targetPoint._y,
                thisPint._z - targetPoint._z);
        }
        public  string ToString(string separator)
        {
            return _x + separator + _y + separator + _z;
        }
        public override string ToString()
        {
            return ToString(",");
        }
    }
}
